#include "FASockServer/IServerImpl.h"



//一个新客户端连接上服务器了  
//当此函数被调用时，libevent已经帮我们accept了这个客户端。该客户端的
//文件描述符为fd
void IServerImpl::listener_cb(evconnlistener *listener,
	evutil_socket_t fd,
	struct sockaddr *sock,
	int socklen,
	void *arg)
{
	printf("accept a client %d\n", fd);

	event_base *base = (event_base*)arg;

	//为这个客户端分配一个bufferevent  
	bufferevent *bev = bufferevent_socket_new(base,
		fd,
		BEV_OPT_CLOSE_ON_FREE);

	bufferevent_setcb(bev, socket_read_cb, NULL, socket_event_cb, NULL);
	bufferevent_enable(bev, EV_READ | EV_PERSIST);
	
	SERVER->AddClient(bev);
	
}


void IServerImpl::socket_read_cb(bufferevent *bev, void *arg)
{
	int32_t len = 0;
	HEAD head;
	char msg[SOCK_BUFFER];
	int32_t alen = evbuffer_get_length(INPUT_BUFFER(bev));

	len = bufferevent_read(bev, &head, sizeof(head));
	alen -= len;

	while (len == sizeof(head))
	{
		bool handle = false;
		if (head.len == 0)
		{
			handle = true;
		}
		else
		{
			len = bufferevent_read(bev, msg, head.len * sizeof(char));
			if (len == head.len)
			{
				handle = true;
				alen -= len;
			}
		}

		if (handle == true)
			SERVER->GetHandle()->Recv(bev, head.id, msg, len);

		len = bufferevent_read(bev, &head, sizeof(head));
		alen -= len;

		if (alen <= 0)
		{
			return;
		}
	}
	


	//m_pHandle->Recv()

}

void IServerImpl::Send(bufferevent *bev,int32_t msgID, char *pData, int nLength)
{
	char msg[SOCK_BUFFER];
	HEAD head;
	head.id = msgID;
	head.len = nLength;
	memcpy(msg, &head, sizeof(head));
	if(nLength > 0)	
		memcpy(msg + sizeof(head), pData, nLength);
	bufferevent_write(bev, msg, sizeof(head) + nLength);
}

void IServerImpl::BroadCast(int32_t msgID, char *pData, int nLength) 
{
	for (MClientIter it = m_Client.begin(); it != m_Client.end(); ++it)
	{
		Send(it->first,msgID,pData,nLength);
	}
}



void IServerImpl::socket_event_cb(bufferevent *bev, short events, void *arg)
{
	if (events & BEV_EVENT_EOF)
	{
		printf("connection closed\n");
		SERVER->GetHandle()->OnDisconnect();
	}
	else if (events & BEV_EVENT_ERROR)
	{
		printf("some other error\n");
		SERVER->GetHandle()->OnErr();
	}
	
	SERVER->RemoveClient(bev);

	//这将自动close套接字和free读写缓冲区  
	bufferevent_free(bev);
}

///////////////////////////////////////////////////////////////////////////

IServerImpl::IServerImpl()
:m_pHandle(0)
, base(0)
, listener(0)
, listener6(0)
{

}

IServerImpl::IServerImpl(IServerHandle *pHandle)
:m_pHandle(pHandle)
, base(0)
, listener(0)
, listener6(0)
{
}


IServerImpl::~IServerImpl()
{
}


int IServerImpl::Create(int port, IP_ADDRESS ipAddress)
{	
	//evthread_use_pthreads();//enable threads  

	base = event_base_new();

	if (ipAddress == BOTH)
	{
		struct sockaddr_in sin;
		memset(&sin, 0, sizeof(struct sockaddr_in));
		sin.sin_family = AF_INET;
		sin.sin_port = htons(port);
		sin.sin_addr.s_addr = htonl(INADDR_ANY);

		listener = evconnlistener_new_bind(base,
			listener_cb,
			base,
			LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
			10,
			(struct sockaddr*)&sin,
			sizeof(sin));

		struct sockaddr_in6 sin6;
		memset(&sin6, 0, sizeof(struct sockaddr_in6));
		sin6.sin6_family = PF_INET6;
		sin6.sin6_port = htons(port);
		sin6.sin6_addr = in6addr_any;

		listener6 = evconnlistener_new_bind(base,
			listener_cb,
			base,
			LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
			10,
			(struct sockaddr*)&sin,
			sizeof(sin6));
	}
	else if(ipAddress == IPV6)
	{
		struct sockaddr_in6 sin6;
		memset(&sin6, 0, sizeof(struct sockaddr_in6));
		sin6.sin6_family = PF_INET6;
		sin6.sin6_port = htons(port);
		sin6.sin6_addr = in6addr_any;

		listener6 = evconnlistener_new_bind(base,
			listener_cb,
			base,
			LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
			10,
			(struct sockaddr*)&sin6,
			sizeof(sin6));
	}
	else
	{
		//默认IPv4
		struct sockaddr_in sin;
		memset(&sin, 0, sizeof(struct sockaddr_in));
		sin.sin_family = AF_INET;
		sin.sin_port = htons(port);
		sin.sin_addr.s_addr = htonl(INADDR_ANY);

		listener = evconnlistener_new_bind(base,
			listener_cb,
			base,
			LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
			10,
			(struct sockaddr*)&sin,
			sizeof(sin));
	}



	event_base_dispatch(base);

	
	return SUCCESS;
}

int IServerImpl::Release()
{
	evconnlistener_free(listener);
	evconnlistener_free(listener6);
	event_base_free(base);
	return SUCCESS;
}

void IServerImpl::Init(IServerHandle * pHandle)
{
	if (!m_pHandle)
	{
		m_pHandle = pHandle;
	}
	else
	{
		//重复绑定
	}
}

void IServerImpl::AddClient(bufferevent * bev)
{
//	BEV_LOCK(0);
	
	MClientIter it = m_Client.find(bev);
	if (it != m_Client.end())
		return;
	tagClient tc;
	tc.login_time = time(NULL);
	tc.live_time = 0;
	m_Client.insert(make_pair(bev, tc));
	
//	BEV_UNLOCK(0);
}

void IServerImpl::RemoveClient(bufferevent * bev)
{
	MClientIter it = m_Client.find(bev);
	if (it == m_Client.end())
		return;
	m_Client.erase(it);
}